﻿using System;
using System.Collections.Generic;
using System.Text;

using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary ;
using System.IO;

using System.Windows.Forms;

using Kitware .VTK ;


namespace Fu3DEngine
{
    public class FuEngine
    {

        //事件相关
        public event SceneEventA SceneAdded;
        public event SceneEventR SceneRemoved;

        Dictionary<string, SceneBase> sceneDic = new Dictionary<string, SceneBase>();

        //私有化方法，单一模式,只是想用这个模式，还不知道有没有用，哈哈
        protected FuEngine()
        { 
        }

      static  FuEngine fengine;
        public static FuEngine GetEngine()
        {
            if (fengine == null)
            {
                fengine = new FuEngine();

                
            }

            return fengine;
        }


        /// <summary>
        /// 初始化引擎部分
        /// </summary>

     
        public void InitEngine()
        {

         
 
        }

        public bool IsRunning { get; set; }
        public void Run()
        {
            foreach (KeyValuePair<string, SceneBase> item in sceneDic)
            {
                item.Value.Run();

            }

            IsRunning = true;
 
        }

        public void UnLoadAllScene()
        {
            foreach (KeyValuePair <string ,SceneBase > item in sceneDic )
            {
                item.Value.UnloadAllNodes();
                
            }
            sceneDic.Clear();

            IsRunning = false;
        }


        //取得场景的方法
        public SceneBase GetScene(string sid)
        {
            if (sceneDic.ContainsKey(sid))
            {
                return sceneDic[sid];
            }
            else
            {
                return null;
            }
        }

        public void AddScene(SceneBase sb)
        {
            if (sb == null)
            {
                return;
            }
            sceneDic.Add(sb.sid, sb);


            if (SceneAdded != null)
                SceneAdded(sb);

        }

        public void RemoveScene(string sid)
        {
            if (sceneDic .ContainsKey (sid))
                sceneDic .Remove (sid );

            if (SceneRemoved != null)
                SceneRemoved(sid);

        }



        //这后期的升级版本中，实现下面的函数
        //public abstract bool LoadSceneXML(string fname);
        //public abstract bool SaveSceneXML(string fname);

        public bool LoadSceneBinary(string fname)
        {

            BinaryFormatter bf = new BinaryFormatter();

            Stream stream = new FileStream(fname,FileMode.Open  , FileAccess.Write, FileShare.None);


            try
            {

              sceneDic= (Dictionary<string, SceneBase>) bf.Deserialize(stream);



            }
            catch (Exception ex)
            {
                MessageBox.Show("错误：" + ex.Message);
                return false;

            }



            foreach (KeyValuePair<string, SceneBase> item in sceneDic)
            {
                item.Value.Reload();

            }

            return true;
 
        }
        public bool SaveSceneBinary(string fname)
        {

            BinaryFormatter bf = new BinaryFormatter();

            Stream stream = new FileStream(fname, FileMode.Open,FileAccess.Write);


            try {

                bf.Serialize(stream, sceneDic);

              

            }
            catch (Exception ex)
            {
                MessageBox.Show("错误："+ex.Message );
                return false;

            }
              

            return true;

        }

        #region "util method"
        //这里统一封装了随机数，为的是做到相对的真随机
        Random m_rd = new Random();
        public double GetNextRandom()
        {
            return m_rd.NextDouble();
        }

        #endregion
    }
}
